//
// Copyright (C) [2024] Xingyun Integrated Circuit, Inc.
//
// GreenCode was a private technology asset of Xingyun Integrated Circuit， Inc （Confidential）
//  Author: Shawn.Tan
//  Date : 2025.10.28
//
//  History : Initial Version 2025.10.28
//
//
#include "AddressFilteringRegulator.h"

#include "AddressSolutionFilter.h"
#include "AddressSolver.h"
#include "GenRequest.h"
#include "Log.h"

/*!
  \file AddressFilteringRegulator.cc
  \brief Code for managing which address filtering regulator to apply.
*/

using namespace std;

namespace Green {

  AddressFilteringRegulator::AddressFilteringRegulator()
    : Object(), mAddressSolutionFilters()
  {
  }

  AddressFilteringRegulator::AddressFilteringRegulator(const AddressFilteringRegulator& rOther)
    : Object(rOther), mAddressSolutionFilters()
  {
    for (auto addr_filter : rOther.mAddressSolutionFilters) {
      AddressSolutionFilter* clone_ptr = nullptr;
      if (nullptr != addr_filter) {
        clone_ptr = dynamic_cast<AddressSolutionFilter* >(addr_filter->Clone());
      }
      mAddressSolutionFilters.push_back(clone_ptr);
    }
  }

  AddressFilteringRegulator::~AddressFilteringRegulator()
  {
    for (auto addr_filter : mAddressSolutionFilters) {
      delete addr_filter;
    }
  }

  Object* AddressFilteringRegulator::Clone() const
  {
    return new AddressFilteringRegulator(*this);
  }

  const string AddressFilteringRegulator::ToString() const
  {
    return Type();
  }

  void AddressFilteringRegulator::Setup(const Generator* pGen)
  {
    for (auto as_ptr : mAddressSolutionFilters) {
      as_ptr->Setup(pGen);
    }
  }

  void AddressFilteringRegulator::GetAddressSolutionFilters(const AddressingMode& rAddrMode, std::vector<AddressSolutionFilter* >& rSolutionFilters) const
  {
    rSolutionFilters.push_back(mAddressSolutionFilters[uint32(EAddressSolutionFilterType::SpAlignment)]);
    rSolutionFilters.push_back(mAddressSolutionFilters[uint32(EAddressSolutionFilterType::BaseDependency)]);

    if (rAddrMode.ShouldApplyIndexFilters()) {
      rSolutionFilters.push_back(mAddressSolutionFilters[uint32(EAddressSolutionFilterType::IndexDependency)]);
    }
  }

  void AddressFilteringRegulator::GetVmConstraints(const GenPageRequest& rPageReq, const VmMapper& rVmMapper, std::vector<VmConstraint* >& rVmConstraints) const
  {
    bool is_instr = false;
    rPageReq.GetGenBoolAttribute(EPageGenBoolAttrType::InstrAddr, is_instr);

    if (is_instr) {
      GetInstrVmConstraints(rPageReq, rVmMapper, rVmConstraints);
    }
    else {
      GetDataVmConstraints(rPageReq, rVmMapper, rVmConstraints);
    }
  }

}
